package com.fundynamic.learnbydoing.designpatterns.statePattern.withoutPattern.service;

import com.fundynamic.learnbydoing.designpatterns.statePattern.withoutPattern.domain.RegistrationState;
import com.fundynamic.learnbydoing.designpatterns.statePattern.withoutPattern.domain.User;


/**
 * This is a commonly used implementation. The method signature takes an argument what the next, desired, state 
 * should be. In order to do so, there should be a check if that may occur. And if so, some logic is executed.
 * Executing all the logic here, clearly violates the Single Responsibility Principle. You could delegate in that
 * case, and it might be safe for you. Unless you will introduce another method where the next state is relevant.
 * 
 * Your switch (or if/else-if) construction must be duplicated with each new method you add to this interface.
 * If you encounter such a thing, it is wise to refactor to a State Pattern.
 * 
 * @author Stefan
 *
 */
public class RegistrationServiceExampleImpl implements
		RegistrationServiceExample {

	@Override
	public void updateUserRegistrationState(User user, RegistrationState newState) {
		if (newState == RegistrationState.UNKNOWN) {
			throw new IllegalStateException("Cannot update to unknown state");
		} else if (newState == RegistrationState.SIGNEDUP_ACTIVATIONLINK_SENT) {
			if (user.getRegistrationState() != RegistrationState.UNKNOWN) {
				throw new IllegalStateException("Cannot update to SIGNED UP state, from state " + user.getRegistrationState());
			}
			sendActivationEmail(user);
		} else if (newState == RegistrationState.LOGINDATA_SENT) {
			if (user.getRegistrationState() != RegistrationState.SIGNEDUP_ACTIVATIONLINK_SENT) {
				throw new IllegalStateException("Cannot update to LOGINDATA_SENT, from state " + user.getRegistrationState());
			}
			finalizeRegistration(user);
			createAccount(user);
			sendEmailWithAccountDetails(user);
		}

		// update state to requested new state
		user.setRegistrationState(newState);
	}
	

	private void sendEmailWithAccountDetails(User user) {
		// violates SRP
	}

	private void createAccount(User user) {
		// violates SRP
	}

	private void finalizeRegistration(User user) {
		// violates SRP
	}

	private void sendActivationEmail(User user) {
		// violates SRP
	}
}
